package co.edu.uniquindio.ondas.daos;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.Query;

import co.edu.uniquindio.ondas.daos.criterio.Criterio;
import co.edu.uniquindio.ondas.entidades.Institucion;
/**
 * @version 1.0
 * @author Javier
 * 
 * Session Bean implementation class InstitucionDAO
 * 
 * @param Institucion hace referencia a la entidad que va hacer manejada por el DAO.
 * @param Long especifica cual es el tipo de dato de la llave primaria de la entidad. 
 */
public class InstitucionDAO extends DAO<Institucion, Long>{

	/**
	 * Manejador de la Persistencia
	 */
	EntityManager entityManager;
	/**
	 * Metodo constructor 
	 *@param entityManager
	 */
	public InstitucionDAO(EntityManager entityManager) {
		super(entityManager);
		this.entityManager=entityManager;
	}

	@Override
	protected Class<Institucion> getEntityClass() {
		// TODO Auto-generated method stub
		return Institucion.class;
	}
	
	/**
	 * Metodo que permite consultar y obtener la Identificacion de una Institucion dado su nombre
	 * @param nombre
	 * @return Identificacion de Institucion
	 */
	public long getInstitucionId(String nombre)
	{
		Query query=entityManager.createQuery("select inst.identificacion from Institucion inst where inst.direccion=:parametro");
		query.setParameter("parametro", nombre);
		return  (Long) query.getSingleResult();
	}
	
	/**
	 * Metodo que permite consultar y obtener una Institucion dado su valor y nombre de Municipio
	 * @param valor
	 * @param nombreMunicipio
	 * @return Institucion
	 */
	public Institucion getInstitucion(String valor, String nombreMunicipio)
	{
		Query query=entityManager.createQuery("select i from Institucion i where i.nombre=:parametro AND i.municipio.nombre=:parametro1");
		query.setParameter("parametro", valor);
		query.setParameter("parametro1", nombreMunicipio);
		return (Institucion) query.getSingleResult();
	}
	
	/**
	 * Metodo que permite obtener y consultar una lista de Instituciones
	 * @return Lista de Instituciones
	 */
	@SuppressWarnings("unchecked")
	public List<String> getListaInstituciones()
	{
		Query query=entityManager.createQuery("select i.nombre from Institucion i ORDER BY i.nombre");
		return query.getResultList();
	}
	
	/**
	 * Metodo que permite obtener y consultar el Total de Paginas por Instituciones dado su tamano de pagina y una lista de criterios
	 * @param tamanoPag
	 * @param criterios
	 * @return numero Total de paginas por Institucion
	 */
	public long obtenerTotalPaginasInstituciones(int tamanoPag, List<Criterio>criterios)
	{
		String sentencia="SELECT COUNT(i) from Institucion i WHERE i.identificacion >= '0'";
		
		for (Criterio criterio : criterios) {
			switch (criterio.getTipo()) {
			case MUNICIPIO:
				sentencia+=" AND i.municipio.nombre= '"+criterio.getArgumento()+"'";
				break;
				
			case ZONA:
				sentencia+=" AND i.zona.nombre= '"+criterio.getArgumento()+"'";
				break;
				
			case NOMBRE:
				sentencia+=" AND i.nombre= '"+criterio.getArgumento()+"'";
				break;
			default:
				break;
			}
		}
		Query query=entityManager.createQuery(sentencia);
		Long total = (Long) query.getSingleResult();
		return total % tamanoPag != 0 ? (total / tamanoPag) + 1 : total / tamanoPag;
	}
	
	/**
	 * Metodo que permite consultar y obtener un Listado de Institucion dado en numero de paginas, tama;o y la lista de criterios
	 * @param numPag
	 * @param tamanoPag
	 * @param criterios
	 * @return Lista de Instituciones 
	 */
	@SuppressWarnings("unchecked")
	public List<Institucion> obtenerInstituciones(int numPag, int tamanoPag, List<Criterio>criterios)
	{
		String sentencia="SELECT i from Institucion i WHERE i.identificacion >= '0'";
		
		for (Criterio criterio : criterios) {
			switch (criterio.getTipo()) {
			case MUNICIPIO:
				sentencia+=" AND i.municipio.nombre= '"+criterio.getArgumento()+"'";
				break;
				
			case ZONA:
				sentencia+=" AND i.zona.nombre= '"+criterio.getArgumento()+"'";
				break;
				
			case NOMBRE:
				sentencia+=" AND i.nombre= '"+criterio.getArgumento()+"'";
				break;
			default:
				break;
			}
		}
		sentencia+=" ORDER BY i.nombre";
		Query query=entityManager.createQuery(sentencia);
		int primerResultado = (numPag - 1) * tamanoPag;
		query = query.setFirstResult(primerResultado );
		query = query.setMaxResults(tamanoPag);
		return query.getResultList();
	}
	
	
	/**
	 * Metodo que permite consultar y obtener una Lista de Nombre de instituciones
	 * @param criterios
	 * @return Lista de Nonbre de Institucion
	 */
	@SuppressWarnings("unchecked")
	public List<String> getListaNombres(List<Criterio>criterios)
	{
		String sentencia="SELECT i.nombre from Institucion i WHERE i.identificacion >= '0'";
		
		for (Criterio criterio : criterios) {
			switch (criterio.getTipo()) {
			case MUNICIPIO:
				sentencia+=" AND i.municipio.nombre= '"+criterio.getArgumento()+"'";
				break;
				
			case ZONA:
				sentencia+=" AND i.zona.nombre= '"+criterio.getArgumento()+"'";
				break;
				
			default:
				break;
			}
		}
		sentencia+=" ORDER BY i.nombre";
		Query query=entityManager.createQuery(sentencia);
		
		return query.getResultList();
	}
}
